Fortran (1957)
program main
print *, "Hello"
end program main
program factorial_example
implicit none
integer :: n
n = 5
print *, "Factorial of", n, "is", factorial(n)
contains
recursive function factorial(k) result(res)
implicit none
integer, intent(in) :: k
integer :: res
if (k <= 1) then
res = 1
else
res = k * factorial(k - 1)
end if
end function factorial
end program factorial_example
-
Memory management
-
Early FORTRAN (especially FORTRAN IV and FORTRAN 77) primarily used static allocation.
-
Modern Fortran (e.g., Fortran 90 and later) introduced proper Stack-Based Automatic Storage
-
Historically:
-
Static and stack allocation
-
No garbage collector
-
Manual heap via ALLOCATE/DEALLOCATE (Fortran 90+)
-
-
Modern Fortran:
-
Explicit allocation model
-
Deterministic deallocation
-
No GC
-
-
Lisp (1958)
-
Homoiconicity enables powerful compile-time code generation
-
Macros can build domain-specific languages
-
Direct control over memory layouts is possible in many implementations
(defmacro my-when (cond &body body)
`(if ,cond
(progn ,@body)
nil))
(my-when (> 3 2)
(print "executed"))
-
Memory management
-
First language to widely use garbage collection
-
Automatic heap allocation
-
Tracing GC (varies by implementation)
-
No manual memory control in idiomatic code
-
COBOL (1959)
IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO.
PROCEDURE DIVISION.
DISPLAY "HELLO".
STOP RUN.
-
Macros as a key innovation.
-
Memory management
-
Static and automatic storage
-
Programmer-managed data areas
-
Main sections:
-
WORKING-STORAGE SECTION → persistent for entire program run
-
LOCAL-STORAGE SECTION → per-invocation automatic storage (later COBOL standards)
-
LINKAGE SECTION → parameters passed between programs
-
FILE SECTION → buffers for I/O records
-
-
No traditional garbage collector (historically)
-
Modern managed COBOL variants may use GC on JVM/.NET
-
ALGOL (1960)
begin
print("Hello")
end
begin
integer n;
procedure factorial(k);
value k;
integer k;
begin
if k = 0 then
factorial := 1
else
factorial := k * factorial(k - 1)
end;
comment Main program;
n := 5;
outinteger(1, factorial(n));
end
-
Memory management
-
It introduced structured stack-based allocation and lexical scoping, which later shaped languages like C, Pascal, and many modern languages.
-
Each procedure call creates an activation record (stack frame).
-
Local variables are allocated when the procedure is entered.
-
Memory is automatically reclaimed when the procedure returns
-
-
ALGOL 60 had very limited heap allocation.
-
Mostly stack-based
-
Arrays could have runtime bounds
-
Some implementations supported
ownvariables (static storage)
-
-
Limitations of ALGOL 60:
-
No general-purpose heap with malloc/free
-
No garbage collector in standard ALGOL 60
-
No pointers in the modern sense
-
No manual memory management
-
-
Later descendants (ALGOL W, ALGOL 68) introduced heap allocation and garbage collection.
-
Basic (1964)
-
Beginner-friendly general language (many dialects).
LET X = 42
PRINT "Value: "; X
-
Memory management
-
Varies heavily by dialect.
-
Classic BASIC:
-
Static and simple heap management
-
Often no GC
-
Interpreter-managed memory
-
-
Modern BASIC (e.g., VB family):
-
Garbage collected (.NET)
-
Or reference counting (VB6 era)
-
-
APL (1966)
+/ 1 2 3 4 5
∘.×⍳5
-
Memory management
-
Automatic garbage collection
-
Heavy heap allocation for arrays
-
Copy-on-write in many implementations
-
No manual memory control
-
Large temporary array pressure common
-
Pascal (1970)
-
Structured systems and teaching language.
program Main;
var
x: Integer;
begin
x := 42;
writeln('Value: ', x);
end.
program CalculateAverage;
var
numbers: array[1..10] of real;
sum, average: real;
i: integer;
begin
sum := 0;
for i := 1 to 10 do
begin
write('Enter number ', i, ': ');
readln(numbers[i]);
sum := sum + numbers[i];
end;
average := sum / 10;
writeln('The average is: ', average:0:2);
end.
-
Pascal .
-
Memory management
-
Stack allocation for locals
-
Manual heap via new / dispose
-
No garbage collector in classic Pascal
-
Deterministic lifetimes
-
Static data segments supported
-
SmallTalk (1962)
-
Pure object-oriented environment.
| x |
x := 42.
Transcript show: 'Value: ', x printString; cr.
-
Memory management
-
Automatic garbage collection
-
Historically generational collectors
-
Image-based heap
-
Everything is heap-allocated objects
-
No manual memory control
-
C (1972)
#include <stdio.h>
int main(void) {
int x = 42;
printf("Value: %d\n", x);
return 0;
}
-
Memory management
-
Manual memory management (malloc, free)
-
Stack allocation for automatic variables
-
No garbage collector
-
No lifetime tracking by compiler
-
Undefined behavior possible on misuse
-
ML / Meta Language (1973)
-
Functional with type inference
datatype tree =
Leaf
| Node of int * tree * tree
fun sum t =
case t of
Leaf => 0
| Node (v, l, r) => v + sum l + sum r
-
Memory management
-
Automatic garbage collection
-
Typically generational collectors
-
Immutable data emphasis
-
No manual memory management
-
Scheme (1975)
-
Minimalist functional Lisp dialect
(define (sum n acc)
(if (= n 0)
acc
(sum (- n 1) (+ acc n))))
(sum 1000000 0)
-
Memory management
-
Automatic garbage collection
-
Usually generational copying GC
-
Proper tail calls reduce stack pressure
-
No manual memory control
-
Ada (1980)
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
X : Integer := 42;
begin
Put_Line("Value: " & Integer'Image(X));
end Main;
-
Memory management
-
Primarily manual (new + explicit deallocation)
-
Stack allocation common
-
Optional controlled types (RAII-like)
-
No mandatory GC
-
Deterministic finalization supported
-
MatLab (1984)
-
Numerical computing environment.
x = 42;
disp(['Value: ', num2str(x)]);
-
Memory management
-
Automatic garbage collection (implementation-specific)
-
Reference counting + copy-on-write for arrays
-
Large heap allocations for matrices
-
No manual free in user code
-
Temporary array pressure significant
-
Objective-C (1984)
#import <Foundation/Foundation.h>
int main() {
@autoreleasepool {
int x = 42;
NSLog(@"Value: %d", x);
}
}
-
Memory management
-
Historically:
-
Manual retain/release
-
-
Modern (Apple platforms):
-
ARC (Automatic Reference Counting)
-
Deterministic destruction
-
Weak references for cycles
-
Manual malloc/free still available via C
-
-
Common Lisp (1984)
-
powerful macro system
-
Lisp family evolution
-
practical large-scale Lisp
-
Optional static typing
(defun dot (a b)
(declare (type (simple-array double-float (*)) a b)
(optimize (speed 3) (safety 0)))
(let ((sum 0.0d0))
(dotimes (i (length a) sum)
(incf sum (* (aref a i) (aref b i))))))
-
Memory management
-
Automatic garbage collection
-
Typically generational, implementation-specific
-
Dynamic heap allocation
-
Manual memory rarely exposed
-
Some implementations allow tuning
-
C++ (1985)
#include <iostream>
int main() {
int x = 42;
std::cout << "Value: " << x << "\n";
}
-
Memory management
-
Manual allocation (new/delete, malloc/free)
-
RAII deterministic destruction
-
Smart pointers (unique_ptr, shared_ptr)
-
Stack vs heap control
-
No built-in GC
-
Perl (1987)
my $x = 42;
print "Value: $x\n";
#!/usr/bin/perl
use strict;
use warnings;
# Variables
my $name = "Alice";
my $age = 30;
print "Name: $name\n";
print "Age: $age\n";
# Conditional
if ($age >= 18) {
print "$name is an adult.\n";
} else {
print "$name is a minor.\n";
}
# Array
my @fruits = ("apple", "banana", "orange");
print "First fruit: $fruits[0]\n";
print "All fruits:\n";
foreach my $fruit (@fruits) {
print "- $fruit\n";
}
# Hash (associative array)
my %person = (
name => "Bob",
city => "São Paulo",
job => "Developer"
);
print "Person info:\n";
while (my ($key, $value) = each %person) {
print "$key => $value\n";
}
# Loop
print "Counting:\n";
for (my $i = 1; $i <= 5; $i++) {
print "$i\n";
}
# File write example
my $filename = "output.txt";
open(my $fh, '>', $filename) or die "Cannot open file: $!";
print $fh "Hello from Perl!\n";
close($fh);
print "File '$filename' written successfully.\n";
-
Memory management
-
Reference counting primary
-
Cycle detection in modern Perl
-
Deterministic destruction in many cases
-
No manual free in user code
-
Internal arenas used by interpreter
-
Haskell (1990)
-
Purely functional, lazy, strongly typed
module Main (main) where -- not needed in interpreter, is the default in a module file
main :: IO () -- the compiler can infer this type definition
main = putStrLn "Hello, World!"
factorial :: (Integral a) => a -> a
-- Using recursion (with the "ifthenelse" expression)
factorial n = if n < 2
then 1
else n * factorial (n - 1)
-- Using recursion (with pattern matching)
factorial 0 = 1
factorial n = n * factorial (n - 1)
-- Using recursion (with guards)
factorial n
| n < 2 = 1
| otherwise = n * factorial (n - 1)
-- Using a list and the "product" function
factorial n = product [1..n]
-- Using fold (implements "product")
factorial n = foldl (*) 1 [1..n]
-- Point-free style
factorial = foldr (*) 1 . enumFromTo 1
Visual Basic (1991)
Module Program
Sub Main()
Dim x As Integer = 42
Console.WriteLine($"Value: {x}")
End Sub
End Module
-
Memory management
-
.NET garbage collector (VB.NET)
-
Generational GC
-
Value types on stack
-
IDisposable for resources
-
Python (1991)
-
General-purpose high-level language.
x = 42
print(f"Value: {x}")
-
Memory management
-
Reference counting (primary)
-
Cycle-detecting garbage collector
-
Deterministic destruction for most objects
-
No manual free in normal code
-
R (1993)
-
Statistical computing language.
x <- 42
cat("Value:", x, "\n")
-
Memory management
-
Automatic garbage collection
-
Copy-on-modify semantics
-
Reference counting internally
-
Heavy heap usage for vectors/data frames
-
No manual memory control
-
Lua (1993)
-
Lightweight embeddable scripting language.
local x = 42
print("Value:", x)
-
Memory management
-
Incremental garbage collector
-
Generational mode in modern Lua
-
Fully heap managed
-
C API allows manual allocations outside VM
-
Delphi (1995)
-
RAD native development.
program Main;
begin
var x: Integer := 42;
Writeln('Value: ', x);
end.
-
Memory management
-
Objects: manual (Free) historically
-
Modern Delphi:
-
ARC on some platforms (mobile era)
-
Manual ownership still common
-
Strings and dynamic arrays are reference-counted
-
No tracing GC
-
Deterministic destruction via Free
-
Java (1995)
-
Enterprise and cross-platform systems.
public class Main {
public static void main(String[] args) {
int x = 42;
System.out.println("Value: " + x);
}
}
-
Memory management
-
Automatic garbage collection
-
Multiple collectors (G1, ZGC, Shenandoah, etc.)
-
Heap + stack model
-
No manual free
-
Escape analysis for stack allocation
-
JavaScript (1995)
-
Dynamic language for web and servers.
const x = 42;
console.log(`Value: ${x}`);
-
Memory management
-
Automatic garbage collection
-
Typically generational mark-and-sweep
-
No manual free
-
Objects allocated on heap
-
Engines (e.g., V8) optimize with escape analysis
-
PHP (1995)
<?php
$x = 42;
echo "Value: $x\n";
-
Embedded in HTML
-
Massive web ecosystem
-
Dynamic typing
-
Simple deployment model
-
Memory management
-
Reference counting
-
Cycle collector (modern PHP)
-
Request-scoped memory model
-
No manual free in userland
-
Ruby (1995)
x = 42
puts "Value: #{x}"
-
Memory management
-
Automatic garbage collection
-
Modern Ruby uses generational + incremental GC
-
Fully heap-allocated objects
-
No manual memory management
-
Erlang (1996)
-
Highly concurrent, fault-tolerant distributed systems.
-module(main).
-export([main/0]).
main() ->
X = 42,
io:format("Value: ~p~n", [X]).
-
Memory management
-
Per-process garbage collection
-
Each process has its own heap
-
Mostly generational copying GC
-
No manual memory control
-
Immutable data model
-
OCaml (1996)
-
Native code compiler
-
Efficient functional runtime
type 'a vec =
| V2 of 'a * 'a
| V3 of 'a * 'a * 'a
let dot a b =
match a, b with
| V2 (x1,y1), V2 (x2,y2) -> x1*x2 + y1*y2
| V3 (x1,y1,z1), V3 (x2,y2,z2) -> x1*x2 + y1*y2 + z1*z2
| _ -> invalid_arg "dim"
-
Memory management
-
Automatic garbage collection
-
Generational GC with minor/major heaps
-
Moving collector for young generation
-
Immutable data heavily optimized
-
Manual memory via C FFI when needed
-
GML / GameMaker Language (1999)
-
Used in GameMaker
var x = 42;
show_debug_message("Value: " + string(x));
-
Memory management
-
Automatic garbage collection (modern GMS2)
-
Engine-managed instances
-
No manual memory control
-
Older versions relied heavily on engine ownership
-
C# (2000)
using System;
class Program {
static void Main() {
int x = 42;
Console.WriteLine($"Value: {x}");
}
}
-
Memory management
-
Automatic garbage collection
-
Generational GC in .NET
-
Stack allocation for value types
-
IDisposable for deterministic resource cleanup
-
unsafe allows manual memory when needed
-
D (2001)(2026-02-20
import std.stdio;
void main() {
int x = 42;
writeln("Value: ", x);
}
import core.stdc.stdlib;
void main() {
int* p = cast(int*)malloc(int.sizeof);
*p = 42;
free(p);
}
import std.stdio;
import std.file;
import std.array;
void main()
{
// Variables
string name = "Alice";
int age = 30;
writeln("Name: ", name);
writeln("Age: ", age);
// Conditional
if (age >= 18)
{
writeln(name, " is an adult.");
}
else
{
writeln(name, " is a minor.");
}
// Dynamic array
string[] fruits = ["apple", "banana", "orange"];
writeln("First fruit: ", fruits[0]);
writeln("All fruits:");
foreach (fruit; fruits)
{
writeln("- ", fruit);
}
// Associative array (hash map)
string[string] person;
person["name"] = "Bob";
person["city"] = "São Paulo";
person["job"] = "Developer";
writeln("Person info:");
foreach (key, value; person)
{
writeln(key, " => ", value);
}
// Loop
writeln("Counting:");
for (int i = 1; i <= 5; i++)
{
writeln(i);
}
// File write example
string filename = "output.txt";
write(filename, "Hello from D!\n");
writeln("File '", filename, "' written successfully.");
}
-
D Lang .
-
Direct C interop (extern(C))
-
Compile-time function execution (CTFE)
-
Value semantics + slices
-
Memory management
-
Built-in garbage collector (default)
-
@nogc mode for GC-free code
-
-
Manual memory via malloc/free
-
Reference counting possible
-
Stack allocation supported
-
Groovy (2003)
-
Dynamic language for the JVM with Java interoperability.
def x = 42
println "Value: $x"
-
Memory management
-
JVM garbage collection
-
Same collectors as Java
-
Objects heap allocated
-
No manual memory control
-
Escape analysis handled by JVM
-
Scala (2004)
-
Functional + OOP on the JVM.
object Main extends App {
val x = 42
println(s"Value: $x")
}
-
Memory management
-
JVM garbage collection
-
Same collectors as Java
-
No manual memory control
-
Haxe (2005)
-
multi-target language (JS, C++, C#, etc.).
class Main {
static function main() {
var x = 42;
trace("Value: " + x);
}
}
-
Memory management
-
Depends on compilation target
-
JS target → GC
-
C++ target (hxcpp) → GC (Boehm or hxcpp GC)
-
C# / Java targets → host GC
-
No manual memory control in typical usage
-
F# (2005)
-
Functional-first language on .NET.
[<EntryPoint>]
let main _ =
let x = 42
printfn "Value: %d" x
0
-
Memory management
-
.NET generational garbage collector
-
Value types allocated on stack
-
Reference types on heap
-
IDisposable pattern for deterministic resource cleanup
-
No manual free in safe code
-
stackalloc and Span
available for low-level work
-
Vala (2006)
-
High-level language compiling to C, mainly for GNOME.
public class ExampleApp : Gtk.Application {
public ExampleApp () {
Object (application_id: "com.example.App");
}
public override void activate () {
var win = new Gtk.ApplicationWindow (this);
var btn = new Gtk.Button.with_label ("Hello World");
btn.clicked.connect (win.close);
win.child = btn;
win.present ();
}
public static int main (string[] args) {
var app = new ExampleApp ();
return app.run (args);
}
}
-
Memory management
-
GObject reference counting
-
Automatic ref management in most cases
-
Compiles to C
-
Manual memory possible via C interop
-
No tracing GC
-
Clojure (2007)
(def x 42)
(println (str "Value: " x))
-
JVM interop
-
Memory management
-
JVM garbage collection
-
Immutable persistent structures
-
No manual memory control
-
Nim (2008)
import std/strformat
type
Person = object
name: string
age: Natural # Ensures the age is positive
let people = [
Person(name: "John", age: 45),
Person(name: "Kate", age: 30)
]
for person in people:
# Type-safe string interpolation,
# evaluated at compile time.
echo(fmt"{person.name} is {person.age} years old")
# Thanks to Nim's 'iterator' and 'yield' constructs,
# iterators are as easy to write as ordinary
# functions. They are compiled to inline loops.
iterator oddNumbers[Idx, T](a: array[Idx, T]): T =
for x in a:
if x mod 2 == 1:
yield x
for odd in oddNumbers([3, 6, 9, 12, 15, 18]):
echo odd
# Use Nim's macro system to transform a dense
# data-centric description of x86 instructions
# into lookup tables that are used by
# assemblers and JITs.
import macros, strutils
macro toLookupTable(data: static[string]): untyped =
result = newTree(nnkBracket)
for w in data.split(';'):
result.add newLit(w)
const
data = "mov;btc;cli;xor"
opcodes = toLookupTable(data)
for o in opcodes:
echo o
-
Nim .
-
Memory management
-
Historically GC (mark-and-sweep)
-
Modern Nim supports:
-
ARC/ORC (deterministic ref counting)
-
Optional GC
-
-
Manual memory via alloc/dealloc
-
Stack allocation for value types
-
CoffeeScript (2009)
-
Syntactic sugar over JavaScript.
x = 42
console.log "Value: #{x}"
-
Memory management
-
Inherits JavaScript GC
-
Fully automatic
-
Engine dependent
-
Go (2009)
-
Simple concurrent systems language.
package main
import "fmt"
func main() {
x := 42
fmt.Println("Value:", x)
}
package main
import (
"fmt"
"os"
)
// Function
func greet(name string) string {
return "Hello, " + name + "!"
}
func main() {
// Variables
name := "Alice"
age := 30
fmt.Println("Name:", name)
fmt.Println("Age:", age)
// Conditional
if age >= 18 {
fmt.Println(name, "is an adult.")
} else {
fmt.Println(name, "is a minor.")
}
// Slice (dynamic array)
fruits := []string{"apple", "banana", "orange"}
fmt.Println("First fruit:", fruits[0])
fmt.Println("All fruits:")
for _, fruit := range fruits {
fmt.Println("-", fruit)
}
// Map (hash table)
person := map[string]string{
"name": "Bob",
"city": "São Paulo",
"job": "Developer",
}
fmt.Println("Person info:")
for k, v := range person {
fmt.Printf("%s => %s\n", k, v)
}
// Loop
fmt.Println("Counting:")
for i := 1; i <= 5; i++ {
fmt.Println(i)
}
// Call function
fmt.Println(greet("World"))
// File write example
filename := "output.txt"
err := os.WriteFile(filename, []byte("Hello from Go!\n"), 0644)
if err != nil {
fmt.Println("Error writing file:", err)
return
}
fmt.Println("File", filename, "written successfully.")
}
-
Memory management
-
Automatic garbage collection
-
Concurrent tri-color mark-and-sweep
-
Stack growth managed by runtime
-
No manual free
-
Escape analysis for stack allocation
-
Rust (2010)
-
Systems programming with strong safety guarantees.
use std::collections::HashMap;
use std::fs;
// Function
fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
fn main() {
// Variables
let name = "Alice";
let age = 30;
println!("Name: {}", name);
println!("Age: {}", age);
// Conditional
if age >= 18 {
println!("{} is an adult.", name);
} else {
println!("{} is a minor.", name);
}
// Vector (dynamic array)
let fruits = vec!["apple", "banana", "orange"];
println!("First fruit: {}", fruits[0]);
println!("All fruits:");
for fruit in &fruits {
println!("- {}", fruit);
}
// HashMap
let mut person: HashMap<&str, &str> = HashMap::new();
person.insert("name", "Bob");
person.insert("city", "São Paulo");
person.insert("job", "Developer");
println!("Person info:");
for (key, value) in &person {
println!("{} => {}", key, value);
}
// Loop
println!("Counting:");
for i in 1..=5 {
println!("{}", i);
}
// Call function
println!("{}", greet("World"));
// File write example
let filename = "output.txt";
match fs::write(filename, "Hello from Rust!\n") {
Ok(_) => println!("File '{}' written successfully.", filename),
Err(e) => println!("Error writing file: {}", e),
}
}
-
Memory management
-
Ownership + borrow checker (compile-time)
-
No garbage collector
-
Deterministic destruction (RAII)
-
Optional reference counting (Rc, Arc)
-
Manual allocation via allocators when needed
-
Kotlin (2011)
-
Modern JVM and multiplatform language.
import java.io.File
// Function
fun greet(name: String): String {
return "Hello, $name!"
}
fun main() {
// Variables
val name = "Alice"
val age = 30
println("Name: $name")
println("Age: $age")
// Conditional
if (age >= 18) {
println("$name is an adult.")
} else {
println("$name is a minor.")
}
// List (dynamic array)
val fruits = listOf("apple", "banana", "orange")
println("First fruit: ${fruits[0]}")
println("All fruits:")
for (fruit in fruits) {
println("- $fruit")
}
// Map
val person = mapOf(
"name" to "Bob",
"city" to "São Paulo",
"job" to "Developer"
)
println("Person info:")
for ((key, value) in person) {
println("$key => $value")
}
// Loop
println("Counting:")
for (i in 1..5) {
println(i)
}
// Call function
println(greet("World"))
// File write example
val filename = "output.txt"
File(filename).writeText("Hello from Kotlin!\n")
println("File '$filename' written successfully.")
}
-
Memory management
-
JVM → garbage collected
-
Kotlin/Native → ARC + cycle collector
-
Kotlin/JS → GC via JS engine
-
No manual free
-
Dart (2011)
-
Client apps (Flutter) and web.
import 'dart:io';
// Function
String greet(String name) {
return 'Hello, $name!';
}
void main() {
// Variables
String name = 'Alice';
int age = 30;
print('Name: $name');
print('Age: $age');
// Conditional
if (age >= 18) {
print('$name is an adult.');
} else {
print('$name is a minor.');
}
// List (dynamic array)
List<String> fruits = ['apple', 'banana', 'orange'];
print('First fruit: ${fruits[0]}');
print('All fruits:');
for (var fruit in fruits) {
print('- $fruit');
}
// Map
Map<String, String> person = {
'name': 'Bob',
'city': 'São Paulo',
'job': 'Developer',
};
print('Person info:');
person.forEach((key, value) {
print('$key => $value');
});
// Loop
print('Counting:');
for (int i = 1; i <= 5; i++) {
print(i);
}
// Call function
print(greet('World'));
// File write example
String filename = 'output.txt';
File(filename).writeAsStringSync('Hello from Dart!\n');
print("File '$filename' written successfully.");
}
-
Memory management
-
Automatic garbage collection
-
Generational GC in Dart VM
-
AOT builds still GC-managed
-
No manual memory control
-
Elixir (2011)
-
Functional concurrent systems.
-
Runs on Erlang VM (BEAM).
# Function
defmodule Example do
def greet(name) do
"Hello, #{name}!"
end
end
defmodule Main do
def run do
# Variables (immutable)
name = "Alice"
age = 30
IO.puts("Name: #{name}")
IO.puts("Age: #{age}")
# Conditional
if age >= 18 do
IO.puts("#{name} is an adult.")
else
IO.puts("#{name} is a minor.")
end
# List
fruits = ["apple", "banana", "orange"]
IO.puts("First fruit: #{Enum.at(fruits, 0)}")
IO.puts("All fruits:")
Enum.each(fruits, fn fruit ->
IO.puts("- #{fruit}")
end)
# Map
person = %{
name: "Bob",
city: "São Paulo",
job: "Developer"
}
IO.puts("Person info:")
Enum.each(person, fn {key, value} ->
IO.puts("#{key} => #{value}")
end)
# Loop via range
IO.puts("Counting:")
Enum.each(1..5, fn i ->
IO.puts(i)
end)
# Call function
IO.puts(Example.greet("World"))
# File write example
filename = "output.txt"
File.write!(filename, "Hello from Elixir!\n")
IO.puts("File '#{filename}' written successfully.")
end
end
Main.run()
-
Memory management
-
Automatic garbage collection
-
Per-process heap GC (very important)
-
Lightweight isolated processes
-
No manual memory control
-
C2 (2011)
#include <stdio.h>
#include <stdlib.h>
// Function
const char* greet(const char* name) {
return "Hello from C2!";
}
// Struct
struct Person {
const char* name;
const char* city;
const char* job;
};
int main() {
// Variables
const char* name = "Alice";
int age = 30;
printf("Name: %s\n", name);
printf("Age: %d\n", age);
// Conditional
if (age >= 18) {
printf("%s is an adult.\n", name);
} else {
printf("%s is a minor.\n", name);
}
// Array
const char* fruits[] = {"apple", "banana", "orange"};
printf("First fruit: %s\n", fruits[0]);
printf("All fruits:\n");
for (int i = 0; i < 3; i++) {
printf("- %s\n", fruits[i]);
}
// Struct usage
struct Person person = {
.name = "Bob",
.city = "São Paulo",
.job = "Developer"
};
printf("Person info:\n");
printf("name => %s\n", person.name);
printf("city => %s\n", person.city);
printf("job => %s\n", person.job);
// Loop
printf("Counting:\n");
for (int i = 1; i <= 5; i++) {
printf("%d\n", i);
}
// Call function
printf("%s\n", greet("World"));
// File write example
const char* filename = "output.txt";
FILE* f = fopen(filename, "w");
if (!f) {
perror("Error opening file");
return 1;
}
fprintf(f, "Hello from C2!\n");
fclose(f);
printf("File '%s' written successfully.\n", filename);
return 0;
}
-
Memory management
-
Manual memory (C-like)
-
No garbage collector
-
Stack allocation
-
Predictable layout
-
TypeScript (2012)
-
Statically typed superset of JavaScript.
const x: number = 42;
console.log(`Value: ${x}`);
-
Memory management
-
Same as JavaScript runtime
-
Automatic GC (engine-dependent)
-
No manual memory control
-
Julia (2012)
-
High-performance scientific computing.
x = 42
println("Value: $x")
-
Memory management
-
Automatic garbage collection
-
Generational mark-and-sweep
-
Stack allocation for some immutables
-
Manual memory possible via Ptr and ccall
-
Swift (2014)
-
Systems-capable language for Apple platforms.
import Foundation
// Function
func greet(_ name: String) -> String {
return "Hello, \(name)!"
}
func main() {
// Variables
let name = "Alice"
let age = 30
print("Name: \(name)")
print("Age: \(age)")
// Conditional
if age >= 18 {
print("\(name) is an adult.")
} else {
print("\(name) is a minor.")
}
// Array
let fruits = ["apple", "banana", "orange"]
print("First fruit: \(fruits[0])")
print("All fruits:")
for fruit in fruits {
print("- \(fruit)")
}
// Dictionary
let person: [String: String] = [
"name": "Bob",
"city": "São Paulo",
"job": "Developer"
]
print("Person info:")
for (key, value) in person {
print("\(key) => \(value)")
}
// Loop
print("Counting:")
for i in 1...5 {
print(i)
}
// Call function
print(greet("World"))
// File write example
let filename = "output.txt"
let content = "Hello from Swift!\n"
do {
try content.write(toFile: filename, atomically: true, encoding: .utf8)
print("File '\(filename)' written successfully.")
} catch {
print("Error writing file: \(error)")
}
}
main()
-
Memory management
-
Automatic Reference Counting (ARC)
-
Deterministic destruction
-
Weak/unowned references for cycles
-
Manual memory possible via unsafe pointers
-
Hack (2014)
-
Statically typed evolution of PHP for large codebases.
<?hh
function main(): void {
$x = 42;
echo "Value: $x\n";
}
-
Memory management
-
Reference counting (HHVM)
-
Cycle detection
-
Managed heap
-
No manual control in typical code
-
Crystal (2014)
-
Ruby-like syntax with native performance.
x = 42
puts "Value: #{x}"
-
Memory management
-
Automatic garbage collection (Boehm GC historically; modern incremental GC)
-
Compiles to native code
-
No manual free
-
Stack allocation possible via compiler analysis
-
Faster than Ruby, still GC pauses exist.
-
GDScript (2014)
-
Python-like scripting for Godot.
func _ready():
var x = 42
print("Value: ", x)
-
Memory management
-
Reference counting for Objects
-
Engine-managed memory
-
Automatic cleanup when nodes freed
-
No manual free for most gameplay code
-
Raku (2015)
-
Modern multi-paradigm language evolved from Perl.
class Circle {
has $.radius;
method area { π * $.radius² }
}
my @radii = 1,2,4...256;
my @circles = map { Circle.new(:$^radius) }, @radii;
my $total-area = [+] @circles».area;
say "Total area: $total-area";
-
Raku .
Jai (2015)
#import "Basic";
// Procedure
greet :: (name: string) -> string {
return tprint("Hello, %!", name);
}
// Struct
Person :: struct {
name: string;
city: string;
job: string;
}
main :: () {
// Variables
name := "Alice";
age := 30;
print("Name: %\n", name);
print("Age: %\n", age);
// Conditional
if age >= 18 {
print("% is an adult.\n", name);
} else {
print("% is a minor.\n", name);
}
// Array
fruits := .["apple", "banana", "orange"];
print("First fruit: %\n", fruits[0]);
print("All fruits:\n");
for fruit: fruits {
print("- %\n", fruit);
}
// Struct usage
person := Person.{
name = "Bob",
city = "São Paulo",
job = "Developer",
};
print("Person info:\n");
print("name => %\n", person.name);
print("city => %\n", person.city);
print("job => %\n", person.job);
// Loop
print("Counting:\n");
for i := 1; i <= 5; i += 1 {
print("%\n", i);
}
// Call procedure
print("%\n", greet("World"));
// File write example
filename := "output.txt";
file, ok := file_open(filename, .WRITE);
if ok {
file_write_string(file, "Hello from Jai!\n");
file_close(file);
print("File '%' written successfully.\n", filename);
} else {
print("Error opening file.\n");
}
}
-
Memory management
-
Manual memory management
-
Custom allocators emphasized
-
No mandatory GC
-
Designed for arena-style allocation
-
Deterministic by design
-
Zig (2016)
const std = @import("std");
// Function
fn greet(name: []const u8) []const u8 {
_ = name;
return "Hello from Zig!";
}
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
// Variables
const name = "Alice";
const age: u32 = 30;
try stdout.print("Name: {s}\n", .{name});
try stdout.print("Age: {}\n", .{age});
// Conditional
if (age >= 18) {
try stdout.print("{s} is an adult.\n", .{name});
} else {
try stdout.print("{s} is a minor.\n", .{name});
}
// Array
const fruits = [_][]const u8{"apple", "banana", "orange"};
try stdout.print("First fruit: {s}\n", .{fruits[0]});
try stdout.print("All fruits:\n", .{});
for (fruits) |fruit| {
try stdout.print("- {s}\n", .{fruit});
}
// HashMap
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
var person = std.StringHashMap([]const u8).init(allocator);
defer person.deinit();
try person.put("name", "Bob");
try person.put("city", "São Paulo");
try person.put("job", "Developer");
try stdout.print("Person info:\n", .{});
var it = person.iterator();
while (it.next()) |entry| {
try stdout.print("{s} => {s}\n", .{ entry.key_ptr.*, entry.value_ptr.* });
}
// Loop
try stdout.print("Counting:\n", .{});
var i: u32 = 1;
while (i <= 5) : (i += 1) {
try stdout.print("{}\n", .{i});
}
// Call function
try stdout.print("{s}\n", .{greet("World")});
// File write example
const filename = "output.txt";
try std.fs.cwd().writeFile(.{
.sub_path = filename,
.data = "Hello from Zig!\n",
});
try stdout.print("File '{s}' written successfully.\n", .{filename});
}
-
Memory management
-
Explicit allocator passing
-
No hidden allocations
-
No garbage collector
-
Stack allocation encouraged
-
Manual free required
-
Optional arena patterns
-
Odin (2016)
package main
import "core:fmt"
main :: proc() {
x: int = 42
fmt.println("Value:", x)
}
-
Uses LLVM.
-
Memory management
-
Manual memory management
-
Explicit allocators, with default values.
-
No built-in GC (optional libraries exist)
-
Stack allocation supported
-
Designed for data-oriented control
-
C3 (2019)
import std::io;
fn void main() {
int x = 42;
io::printn("Value: {}", x);
}
import std::mem;
import std::io;
fn void main() {
int* p = mem::alloc<int>();
*p = 42;
io::printn("Value: {}", *p);
mem::free(p);
}
-
Has Methods:
struct Foo
{
int i;
}
fn void Foo.next(Foo* this) // <- Method
{
if (this) this.i++;
}
fn void test()
{
Foo foo = { 2 };
foo.next();
foo.next();
// Prints 4
io::printfn("%d", foo.i);
}
-
C3 .
-
Examples .
-
Uses LLVM.
-
Compile-time execution.
-
Clean module system.
-
Memory management
-
Manual allocation
-
No GC
-
Optional safety checks
-
Stack + heap control
-
Contracts and safety checks
-
Explicit ownership patterns encouraged
-
-
Macros:
Gleam (2019)
-
Statically typed functional language for BEAM.
import gleam/io
pub fn main() {
let x = 42
io.println("Value: " <> int.to_string(x))
}
pub fn main() {
let subject = process.new_subject()
// Spawn a child green thread
process.spawn(fn() {
// Send a message back to the parent
process.send(subject, "Hello, Joe!")
})
// Wait for the message to arrive
echo process.receive(subject, 100)
}
@external(erlang, "Elixir.HPAX", "new")
pub fn new(size: Int) -> Table
pub fn register_event_handler() {
let el = document.query_selector("a")
element.add_event_listener(el, fn() {
io.println("Clicked!")
})
}
-
Memory management
-
Automatic GC via BEAM
-
Per-process heaps (inherited from Erlang)
-
Immutable data structures
-
No manual memory control
-
V (2019)
fn main() {
x := 42
println('Value: $x')
}
fn main() {
areas := ['game', 'web', 'tools', 'science', 'systems',
'embedded', 'drivers', 'GUI', 'mobile']
for area in areas {
println('Hello, ${area} developers!')
}
}
-
V Lang .
-
Memory management
-
There are 4 ways to manage memory in V:
-
The default is a minimal and a well performing tracing GC.
-
The second way is autofree, it can be enabled with -autofree. It takes care of most objects (~90-100%): the compiler inserts necessary free calls automatically during compilation. Remaining small percentage of objects is freed via GC. The developer doesn't need to change anything in their code. "It just works", like in Python, Go, or Java, except there's no heavy GC tracing everything or expensive RC for each object. Autofree is still experimental and not production ready yet. That's planned for V 1.0.
-
For developers willing to have more low level control, memory can be managed manually with -gc none.
-
Arena allocation is available via v -prealloc.
-
-
Beef (2019)
-
Native language with C# ergonomics.
using System;
class Program {
static void Main() {
int x = 42;
Console.WriteLine($"Value: {x}");
}
}
-
Memory management
-
Deterministic destruction (RAII-style)
-
No mandatory garbage collector
-
Optional GC available
-
Manual allocation supported
-
Value types on stack
-
Fil-C (2021)
Hare (2021)
use fmt;
export fn main() void = {
const greetings = [
"Hello, world!",
"¡Hola Mundo!",
"Γειά σου Κόσμε!",
"Привіт, світе!",
"こんにちは世界!",
];
for (let greeting .. greetings) {
fmt::println(greeting)!;
};
};
let x = 10;
let y: *int = &x; // Guaranteed to be non-null
let z: nullable *int = y; // May be null!
*y; // Valid
*z; // Error: main.ha:6:19: Cannot dereference nullable pointer type
match (z) {
case null =>
abort();
case let z: *int =>
yield *z; // Valid
};
let x: int = if (foo) {
let results = do_work();
yield results.x;
} else 42;
fn io::write(s: *stream, buf: const []u8) (size | io::error);
// ...
sum += match (io::write(s, buf)) {
case let err: io::error =>
match (err) {
case unsupported =>
abort("Expected write to be supported");
case =>
return err;
};
case let n: size =>
process(buf[..n]);
yield n;
};
-
Hare is a systems programming language designed to be simple, stable, and robust. Hare uses a static type system, manual memory management, and a minimal runtime. It is well-suited to writing operating systems, system tools, compilers, networking software, and other low-level, high performance tasks.
-
Demo .
-
QBE Compiler.
-
Expression oriented.
-
Bound checking in arrays and slices.
-
Optional unbound arrays for performance.
-
No NULL value.
-
Non-nullable pointers by default; cannot deref null pointer.
-
Defer.
-
Mandatory error handling.
-
No macros, generics or multithreading.
-
Transparency:
-
No function overloading.
-
No operator overloading.
-
No implicit conversions.
-
-
(2026-02-13) Hare 0.26.0 released.
Carbon (2022)
-
Experimental successor language for C++.
package Main;
fn Main() -> i32 {
var x: i32 = 42;
Print("Value: {0}\n", x);
return 0;
}
// Carbon:
package Geometry;
import Math;
class Circle {
var r: f32;
}
fn PrintTotalArea(circles: [Circle]) {
var area: f32 = 0;
for (c: Circle in circles) {
area += Math.Pi * c.r * c.r;
}
Print("Total area: {0}", area);
}
fn Run() -> i32 {
// A dynamically sized array, like `std::vector`.
var circles: array [Circle] = ({.r = 1.0}, {.r = 2.0});
// Implicitly constructs a slice from the array.
PrintTotalArea(circles);
return 0;
}
-
Carbon .
-
Memory management
-
Manual memory management (C++-like model)
-
No garbage collector by default
-
RAII-oriented design (planned)
-
Interop with C++
-
Mojo (2023)
-
Python-like syntax for high-performance and AI.
fn main():
let x: Int = 42
print("Value:", x)
-
Memory management
-
Ownership-based model (Rust-inspired direction)
-
Manual and automatic strategies planned
-
Value types with stack allocation
-
No traditional GC in performance mode
-
Still evolving
-